/**
  CNOK project, Anyang Normal University, IMP-CAS
  \class TAInterpolate
  \brief Polynomial interpolation. Note that this is a mathematical tool class.
  \author SUN Yazhou, asia.rabbit@163.com
  \since 2020/07/09
  \date Last modified: 2020/07/19 by SUN Yazhou
  \copyright 2020-2023 SUN Yazhou
  \copyright CNOK project, Anyang Normal University, IMP-CAS
*/

#ifndef _TAInterpolate_h_
#define _TAInterpolate_h_

#include <complex>

template <typename T1 = double, typename T = double>
class TAInterpolate{
public:
  TAInterpolate(){}
  virtual ~TAInterpolate(){}

  /// Polynomial interpolation using Neville's algorithm
  /// given n points in arrays x and y, and input xx, this routine returns the
  /// interpolated func value y at xx, and assigning the error estimate to dy.
  /// Ref. Numerical Recipes in C: p109
  static T1 PolyInter(const T *x, const T1 *y, int n, const T &xx, T1 *dy = nullptr);
  /// Polynomial interpolation, same as the above, but using Lagrange's algorithm
  static T1 PolyInterLag(const T *x, const T1 *y, int n, const T &xx, T1 *dy = nullptr);
  /// \param len is the length of array x (or y), so that the program would choose
  /// the closest interval to envelope xx in the center
  /// \param np has the same meaning (n) as in the other overload of PolyInter
  /// \param warn when used for extrapolation, warn set to false can supress
  /// out-of-bounds warning
  static T1 PolyInter(const T *x, const T1 *y, int len, int np, const T &xx,
    T1 *dy = nullptr, bool warn = true);
};

#include "TAInterpolate.hpp"

typedef TAInterpolate<> TAInterpolateD;
typedef TAInterpolate<std::complex<double>> TAInterpolateC;

#endif
